package com.ssy.lingxi.contract.controller;


import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ssy.lingxi.common.controller.BaseController;
import com.ssy.lingxi.contract.constant.SignConstant;
import com.ssy.lingxi.contract.esign.api.SignApi;
import com.ssy.lingxi.contract.esign.constant.EsignConstants;
import com.ssy.lingxi.contract.esign.request.OrganizationNotifyRequest;
import com.ssy.lingxi.contract.esign.request.PersonalNotifyRequest;
import com.ssy.lingxi.contract.esign.request.SignFlowFinshNotifyRequest;
import com.ssy.lingxi.contract.esign.request.SignFlowUpdateNotifyRequest;
import com.ssy.lingxi.contract.esign.response.TransferRandomAmountNotifyRequest;
import com.ssy.lingxi.contract.model.bo.sign.SignAuthNotifyBO;
import com.ssy.lingxi.contract.model.bo.sign.SignFlowNotifyBO;
import com.ssy.lingxi.contract.service.ISignatureAuthService;
import com.ssy.lingxi.contract.service.ISignatureService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

/**
 * e签宝异步回调通知
 */
@Slf4j
@RestController
@RequestMapping
public class EsignNotifyController extends BaseController {

    @Resource
    private ISignatureAuthService signatureAuthService;
    @Resource
    private ISignatureService signatureService;
    @Resource
    private SignApi signApi;

    /**
     * 企业认证回调通知
     * @param request 请求参数
     */
    @PostMapping(value = SignConstant.organizationAuthUri)
    public void organizationAuth(HttpServletRequest request, HttpServletResponse response) {
        Map<String, String> map = getHeadersInfo(request);
        String bodyStr = getRequestBody(request);

        // {"flowId":"1411433214391617315","success":true,"contextId":"f0a7927d-c5f9-4652-a053-1130d86c8fa8","verifycode":"e990492aad163c247495ffffe7c49d4a","serviceId":"1411433214391617315","status":true}
        boolean verifySign = signApi.verifySign(map, bodyStr);
        if (verifySign) {
            OrganizationNotifyRequest notifyRequest = JSONUtil.toBean(bodyStr, OrganizationNotifyRequest.class);

            SignAuthNotifyBO signAuthNotifyBO = new SignAuthNotifyBO();
            signAuthNotifyBO.setFlowId(notifyRequest.getFlowId());

            if (notifyRequest.getSuccess()) {
                signatureAuthService.verifySuccess(signAuthNotifyBO);
                log.info("e签宝回调业务成功结果: {}", JSONUtil.toJsonStr(notifyRequest));
            } else {
                signatureAuthService.verifyFail(signAuthNotifyBO);
                log.info("e签宝回调业务失败结果: {}", JSONUtil.toJsonStr(notifyRequest));
            }
        }

        // 通知成功
        notifySuccess(response);
    }

    /**
     * 随机打款回调通知
     * @param request 请求参数
     */
    @PostMapping(value = SignConstant.transferRandomAmountUri)
    public void transferRandomAmount(HttpServletRequest request, HttpServletResponse response) {
        Map<String, String> map = getHeadersInfo(request);
        String bodyStr = getRequestBody(request);

        // {"msg":"转账交易成功","result":"PAY_SUCCESS","payedTime":1594137600000,"pizId":"f0a7927d-c5f9-4652-a053-1130d86c8fa8","serviceId":"27bb7ac1-aaa7-4425-8463-93a0a8d286d3","projectId":"7438817714"}
        boolean verifySign = signApi.verifySign(map, bodyStr);
        if (verifySign) {
            TransferRandomAmountNotifyRequest notifyRequest = JSONUtil.toBean(bodyStr, TransferRandomAmountNotifyRequest.class);
            if ("PAY_SUCCESS" .equals(notifyRequest.getResult())) {
                log.info("e签宝回调业务成功结果: {}", JSONUtil.toJsonStr(notifyRequest));
            } else {
                log.info("e签宝回调业务失败结果: {}", JSONUtil.toJsonStr(notifyRequest));
            }
        }

        // 通知成功
        notifySuccess(response);
    }

    /**
     * 人脸认证回调通知
     * @param request 请求参数
     */
    @PostMapping(value = SignConstant.faceAuthUri)
    public void faceAuth(HttpServletRequest request, HttpServletResponse response) {
        Map<String, String> map = getHeadersInfo(request);
        String bodyStr = getRequestBody(request);

        // {"flowId":"1411642943567038149","success":true,"verifycode":"5ddb136fb03244b224f599edb609bd80","serviceId":"1411642943567038149","status":true}
        boolean verifySign = signApi.verifySign(map, bodyStr);
        if (verifySign) {
            PersonalNotifyRequest notifyRequest = JSONUtil.toBean(bodyStr, PersonalNotifyRequest.class);

            SignAuthNotifyBO signAuthNotifyBO = new SignAuthNotifyBO();
            signAuthNotifyBO.setFlowId(notifyRequest.getFlowId());

            if (notifyRequest.getSuccess()) {
                signatureAuthService.verifySuccess(signAuthNotifyBO);
                log.info("e签宝回调业务成功结果: {}", JSONUtil.toJsonStr(notifyRequest));
            } else {
                signatureAuthService.verifyFail(signAuthNotifyBO);
                log.info("e签宝回调业务失败结果: {}", JSONUtil.toJsonStr(notifyRequest));
            }
        }

        // 通知成功
        notifySuccess(response);
    }

    /**
     * 运营商认证回调通知
     * @param request 请求参数
     */
    @PostMapping(value = SignConstant.telecomAuthUri)
    public void telecomAuth(HttpServletRequest request, HttpServletResponse response) {
        Map<String, String> map = getHeadersInfo(request);
        String bodyStr = getRequestBody(request);

        // {"flowId":"1412516304664921873","success":true,"verifycode":"230000a46aba8c3aebddda37866c46f4","serviceId":"1412516304664921873","status":true}
        boolean verifySign = signApi.verifySign(map, bodyStr);
        if (verifySign) {
            PersonalNotifyRequest notifyRequest = JSONUtil.toBean(bodyStr, PersonalNotifyRequest.class);

            SignAuthNotifyBO signAuthNotifyBO = new SignAuthNotifyBO();
            signAuthNotifyBO.setFlowId(notifyRequest.getFlowId());

            if (notifyRequest.getSuccess()) {
                signatureAuthService.verifySuccess(signAuthNotifyBO);
                log.info("e签宝回调业务成功结果: {}", JSONUtil.toJsonStr(notifyRequest));
            } else {
                signatureAuthService.verifyFail(signAuthNotifyBO);
                log.info("e签宝回调业务失败结果: {}", JSONUtil.toJsonStr(notifyRequest));
            }
        }

        // 通知成功
        notifySuccess(response);
    }

    /**
     * 流程结束回调通知
     * @param request 请求参数
     */
    @PostMapping(value = SignConstant.singFlowFinish)
    public void singFlowFinish(HttpServletRequest request, HttpServletResponse response) {
        Map<String, String> map = getHeadersInfo(request);
        String bodyStr = getRequestBody(request);
        boolean verifySign = signApi.verifySign(map, bodyStr);

        // {"action":"SIGN_FLOW_UPDATE","flowId":"956be66a5a154d7c98d133bc202ea02f","timestamp":1600172718864}
        // {"businessScence":"购销合同","statusDescription":"完成","createTime":"2020-09-15 20:25:18","action":"SIGN_FLOW_FINISH","endTime":"2020-09-15 20:26:33","flowStatus":"2","flowId":"956be66a5a154d7c98d133bc202ea02f","timestamp":1600172793477}

        JSONObject jsonObject = JSONUtil.parseObj(bodyStr);
        // 打印结果
        log.info("e签宝回调业务成功结果: {}", JSONUtil.toJsonStr(jsonObject));
        if (verifySign) {
            // 签署人签署完成
            if (EsignConstants.Action.SIGN_FLOW_UPDATE.equals(jsonObject.getStr("action"))) {
                SignFlowUpdateNotifyRequest notifyRequest = JSONUtil.toBean(jsonObject, SignFlowUpdateNotifyRequest.class);
                boolean flag = signatureService.updateSignResult(notifyRequest);
                if (!flag) {
                    notifyFail(response);
                }
            }
            // 流程结束
            if (EsignConstants.Action.SIGN_FLOW_FINISH.equals(jsonObject.getStr("action"))) {
                SignFlowFinshNotifyRequest notifyRequest = JSONUtil.toBean(jsonObject, SignFlowFinshNotifyRequest.class);

                SignFlowNotifyBO signFlowNotifyBO = new SignFlowNotifyBO();
                signFlowNotifyBO.setFlowId(notifyRequest.getFlowId());
                signFlowNotifyBO.setStatusDescription(notifyRequest.getStatusDescription());

                boolean flag = false;
                if (EsignConstants.SignFlowStatus.FINISH.equals(notifyRequest.getFlowStatus())) {
                    flag = signatureService.updateNotifySuccess(signFlowNotifyBO);
                } else if (
                        EsignConstants.SignFlowStatus.CANCEL.equals(notifyRequest.getFlowStatus())
                                || EsignConstants.SignFlowStatus.PAST_DUE.equals(notifyRequest.getFlowStatus())
                                || EsignConstants.SignFlowStatus.REJECT.equals(notifyRequest.getFlowStatus())
                ) {
                    flag = signatureService.updateNotifyFail(signFlowNotifyBO);
                }
                if (!flag) {
                    notifyFail(response);
                }
            }
        }

        // 通知成功
        notifySuccess(response);
    }


    /**
     * 通知成功
     * @param response 请求参数
     */
    private void notifySuccess(HttpServletResponse response) {
        response.setStatus(HttpStatus.OK.value());
    }

    /**
     * 通知失败
     * @param response 请求参数
     */
    private void notifyFail(HttpServletResponse response) {
        response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
    }
}
